package com.ainge.easystudy.timeoutcenter;

import com.google.gson.Gson;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 简单连接redis测试
 *
 * @author: Ainge
 * @Time: 2021/8/4 23:18
 */
public class RedisClient {

    public static final Gson gson = new Gson();

    public static final JedisPool jedisPool;

    static {
        // 建立连接池配置参数
        JedisPoolConfig config = new JedisPoolConfig();
        // 最大空闲连接数
        config.setMaxIdle(1);
        // 设置最大阻塞时间，记住是毫秒数milliseconds
        config.setMaxWaitMillis(5000);
        // 最大连接数, 默认8个
        config.setMaxTotal(8);
        // 创建连接池
        jedisPool = new JedisPool(config, "localhost", 6379, 5000, "zhuanji", 0);
    }

    private RedisClient() {
        throw new RuntimeException("RedisClient cannot be instance...");
    }

    public static Jedis getJedis() {
        return jedisPool.getResource();
    }

    public static void returnJedis(Jedis jedis) {
        jedisPool.returnResource(jedis);
    }

    public static void returnBrokenJedis(Jedis jedis) {
        jedisPool.returnBrokenResource(jedis);
    }

    public static void close() {
        jedisPool.destroy();
    }

    public static Long zadd(final String key, final double score, final String member) {
        return executeTemplate(jedis -> jedis.zadd(key, score, member));
    }

    public static Long zadd(final String key, final double score, Serializable object) {
        return executeTemplate(jedis -> jedis.zadd(key, score, gson.toJson(object)));
    }

    public static Long zrem(String key, String ... members) {
        return executeTemplate(jedis -> jedis.zrem(key, members));
    }

    public static Long zrem(String key, Serializable member) {
        return executeTemplate(jedis -> jedis.zrem(key, gson.toJson(member)));
    }

    /**
     * 获取[min,max]区间的所有元素
     *
     * @param key key
     * @param min 左闭区间
     * @param max 右闭区间
     * @return 所有符号的元素
     */
    public static Set<String> zrangeByScore(String key, double min, double max) {
        return executeTemplate(jedis -> jedis.zrangeByScore(key, min, max));
    }

    /**
     * 获取[min,max]区间的所有元素
     *
     * @param key key
     * @param min 左闭区间
     * @param max 右闭区间
     * @param cls 必须实现序列化接口的对象
     * @return 所有符号的元素
     */
    public static <T extends Serializable> List<T> zrangeByScore(String key, double min, double max, Class<T> cls) {
        Set<String> result = executeTemplate(jedis -> jedis.zrangeByScore(key, min, max));
        List<T> list = new ArrayList<>(result.size());
        if (!result.isEmpty()) {
            for (String s : result) {
                list.add(gson.fromJson(s, cls));
            }
        }
        return list;
    }

    private static <T> T executeTemplate(RedisCall<T> call) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return call.execute(jedis);
        } catch (Exception e) {
            returnBrokenJedis(jedis);
            throw e;
        } finally {
            returnJedis(jedis);
        }
    }
}
